package debtbundler.domain.entity.impl;


import static org.junit.Assert.*;

import java.util.Calendar;

import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class AuditFieldTest {
	
	@BeforeClass 
	public static void enableLogging() {
		debtbundler.logging.ConfigurationReader.setDefaultConf();
	}

	@Before
	public void setUp() throws Exception {
	}

	@After
	public void tearDown() throws Exception {
	}
	
	/**
	 * Tests that audit fields createdDate, createdBy,
	 * updatedDate, updatedBy are set as when an entity 
	 * is created.
	 */
	@Test
	public void testAuditFieldsWhenCreated() {
		PersonImpl person = new PersonImpl();
		assertNotNull(person.getCreatedDate());
		assertNotNull(person.getCreatedBy());
		assertEquals(System.getProperty("user.name"), person.getCreatedBy());
		assertNotNull(person.getUpdatedDate());
		assertNotNull(person.getUpdatedBy());
		assertEquals(person.getCreatedDate(), person.getUpdatedDate());
		assertEquals(person.getCreatedBy(), person.getUpdatedBy());
	}
	
	
	/**
	 * Test that audit fields are set when an entity is updated.
	 * They should be set when by the fireUpdateEvent() 
	 * method in AbstractListenableEntity so we don't test every entity.
	 * 
	 * @throws InterruptedException 
	 */
	@Test
	public void testAuditFieldsWhenUpdated() throws InterruptedException {
		PersonImpl person = new PersonImpl();
		Calendar oldUpdatedDate = person.getUpdatedDate();
		
		Thread.sleep(100); // to ensure that next update happens measurably later
		System.setProperty("user.name", "someone"); // to forge a different user as updater
		
		person.setName("New name");
		assertTrue(person.getUpdatedDate().after(oldUpdatedDate));
		assertTrue(person.getUpdatedBy().equals("someone"));
		oldUpdatedDate = person.getUpdatedDate();
		
		SharedCostImpl cost = new SharedCostImpl();
		PaymentImpl payment = new PaymentImpl(person, cost);
		
		Thread.sleep(100); // to ensure that next update happens measurably later
		System.setProperty("user.name", "someone else"); // to forge a different user as updater
		
		person.addPayment(payment);
		assertTrue(person.getUpdatedDate().after(oldUpdatedDate));
		assertTrue(person.getUpdatedBy().equals("someone else"));
		
	}

}
